package com.zjh.document.service.impl;

import com.zjh.document.entity.DTO.FileObject;
import com.zjh.document.entity.VO.MinioFileInfoVO;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class MinIOService {

    @Value("${minio.bucket}")
    private String bucketName;

    @Resource
    private MinioClient minioClient;

    /**
     * 上传文件
     */
    public boolean uploadFile(String bucketName, MultipartFile file, String objectName) {
        try {
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName) // 存储桶
                    .object(objectName) // 文件名
                    .stream(file.getInputStream(), file.getSize(), -1) // 文件内容
                    .contentType(file.getContentType()) // 文件类型
                    .build());
            return true;
        } catch (Exception e) {
            return false;
        }

    }

    /**
     * 删除文件
     */
    public boolean delete(String bucketName, String path) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName) // 存储桶
                    .object(path) // 文件名
                    .build());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 删除给定前缀的所有对象。
     */
    public void deleteFolder(String bucketName, String folderPrefix) throws IOException, NoSuchAlgorithmException, InvalidKeyException, MinioException {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(folderPrefix).recursive(true).build());

        for (Result<Item> result : results) {
            Item item = result.get();
            // 删除每个对象
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(item.objectName())
                            .build());
        }
    }

    public boolean batchDelete(String bucketName, List<String> path) {
        try {
            List<DeleteObject> dos = path.stream().map(DeleteObject::new).collect(Collectors.toList());
            Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
            //必须遍历了迭代器才能删除成功
            for (Result<DeleteError> result : results) {
                DeleteError error = result.get();
                log.error("minio批量删除文件失败：" + error.objectName() + "; " + error.message());
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public List<String> getAllBucket() {
        List<String> res = new ArrayList<>();

        try {
            List<Bucket> buckets = minioClient.listBuckets();
            for (Bucket bucket : buckets) {
                res.add(bucket.name());
            }
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }

        return res;
    }

    public void newFileAndUploadFileToMinio(String fileName, String fileType) throws Exception {
        // 创建临时文件
        File tempFile = File.createTempFile(fileName, fileType);

        // 上传文件到MinIO
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName + "." + fileType)
                        .stream(new FileInputStream(tempFile), tempFile.length(), -1)
                        .contentType("text/plain")
                        .build());

        // 删除临时文件
        tempFile.delete();
    }

    /**
     * 移动MinIO中的文件到另一个目录
     *
     * @param sourceObject    源文件路径（包含文件名）
     * @param targetDirectory 目标目录路径
     * @return 移动成功返回true，否则返回false
     */
    public boolean moveFileInMinio(String sourceObject, String targetDirectory) {
        try {
            // 检查源文件是否存在
            if (!objectExists(sourceObject)) {
                log.error("源文件不存在: {}", sourceObject);
                return false;
            }

            // 确保目标目录格式正确（以/结尾）
            if (!targetDirectory.endsWith("/")) {
                targetDirectory += "/";
            }

            // 从源路径中提取文件名
            String fileName = extractFileName(sourceObject);

            // 构建目标文件路径
            String targetObject = targetDirectory + fileName;

            // 复制文件到新位置
            copyObject(sourceObject, targetObject);

            // 删除原文件
            deleteObject(sourceObject);

            log.info("MinIO文件移动成功: {} -> {}", sourceObject, targetObject);
            return true;

        } catch (Exception e) {
            log.error("MinIO文件移动失败: {}", e.getMessage(), e);
            return false;
        }
    }


    /**
     * 完整的文件夹转移（包括文件夹本身）
     *
     * @param sourceFolder       源文件夹名称（如：folder1）
     * @param targetParentFolder 目标父文件夹路径（如：parent/ 或空字符串表示根目录）
     * @param newFolderName      新文件夹名称（如：folder2，如果为null则保持原名称）
     * @return 转移成功返回true，否则返回false
     */
    public boolean transferFolder(String sourceFolder, String targetParentFolder, String newFolderName) {
        try {
            // 规范化路径
            String sourceFolderPath = normalizeFolderPath(sourceFolder, false);
            String targetParentPath = normalizeFolderPath(targetParentFolder, true);

            // 确定目标文件夹名称
            String finalFolderName = (newFolderName != null && !newFolderName.trim().isEmpty()) ?
                    newFolderName : extractFolderName(sourceFolderPath);

            String targetFolderPath = targetParentPath + finalFolderName + "/";

            log.info("开始转移文件夹: {} -> {}", sourceFolderPath, targetFolderPath);

            // 检查源文件夹是否存在
            if (!folderExists(sourceFolderPath)) {
                log.error("源文件夹不存在: {}", sourceFolderPath);
                return false;
            }

            // 检查目标位置是否冲突
            if (folderExists(targetFolderPath)) {
                log.error("目标文件夹已存在: {}", targetFolderPath);
                return false;
            }

            // 获取源文件夹中的所有内容（包括子文件夹和文件）
            List<MinioObject> allObjects = listAllObjectsInFolder(sourceFolderPath, true);

            if (allObjects.isEmpty()) {
                log.warn("源文件夹为空，创建空目标文件夹");
                // 创建空文件夹标记
                createEmptyFolder(targetFolderPath);
                return true;
            }

            log.info("找到 {} 个对象需要转移", allObjects.size());

            // 转移所有对象
            boolean allSuccess = true;
            int successCount = 0;

            for (MinioObject minioObject : allObjects) {
                String sourceObject = minioObject.getObjectName();
                String targetObject = sourceObject.replace(sourceFolderPath, targetFolderPath);

                boolean success = transferSingleObject(sourceObject, targetObject);
                if (success) {
                    successCount++;
                } else {
                    allSuccess = false;
                    log.error("转移对象失败: {} -> {}", sourceObject, targetObject);
                }
            }

            if (allSuccess) {
                log.info("文件夹转移成功: 共转移 {} 个对象", successCount);

                // 删除源文件夹（如果为空）
                deleteFolderIfEmpty(sourceFolderPath);

            } else {
                log.warn("文件夹部分转移成功: 成功 {} 个，失败 {} 个",
                        successCount, allObjects.size() - successCount);
            }

            return allSuccess;

        } catch (Exception e) {
            log.error("文件夹转移失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 从路径中提取文件夹名称
     */
    private String extractFolderName(String folderPath) {
        folderPath = folderPath.replaceAll("/+$", ""); // 移除末尾的斜杠
        int lastSlashIndex = folderPath.lastIndexOf('/');
        if (lastSlashIndex >= 0) {
            return folderPath.substring(lastSlashIndex + 1);
        }
        return folderPath;
    }

    /**
     * 确保目标对象的父目录存在
     */
    private void ensureParentDirectoriesExist(String objectPath) throws Exception {
        int lastSlashIndex = objectPath.lastIndexOf('/');
        if (lastSlashIndex > 0) {
            String parentPath = objectPath.substring(0, lastSlashIndex + 1);
            if (!folderExists(parentPath)) {
                createEmptyFolder(parentPath);
            }
        }
    }

    /**
     * 创建空文件夹标记
     */
    private void createEmptyFolder(String folderPath) throws Exception {
        // 创建空文件作为文件夹标记
        String markerFile = folderPath + ".folder-marker";
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(markerFile)
                        .stream(new java.io.ByteArrayInputStream(new byte[0]), 0, -1)
                        .build());

        log.debug("创建空文件夹标记: {}", markerFile);
    }

    /**
     * 如果文件夹为空则删除
     */
    private void deleteFolderIfEmpty(String folderPath) throws Exception {
        List<MinioObject> remainingObjects = listAllObjectsInFolder(folderPath, false);
        if (remainingObjects.isEmpty()) {
            // 删除文件夹标记文件（如果有）
            String markerFile = folderPath + ".folder-marker";
            if (objectExists(markerFile)) {
                deleteObject(markerFile);
            }
            log.info("删除空源文件夹: {}", folderPath);
        }
    }

    /**
     * 转移单个对象
     */
    private boolean transferSingleObject(String sourceObject, String targetObject) {
        try {
            // 检查源对象是否存在
            if (!objectExists(sourceObject)) {
                log.error("源对象不存在: {}", sourceObject);
                return false;
            }

            // 确保目标目录存在（创建必要的父目录）
            ensureParentDirectoriesExist(targetObject);

            // 复制对象到新位置
            minioClient.copyObject(
                    CopyObjectArgs.builder()
                            .bucket(bucketName)
                            .object(targetObject)
                            .source(
                                    CopySource.builder()
                                            .bucket(bucketName)
                                            .object(sourceObject)
                                            .build())
                            .build());

            // 删除原对象
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(sourceObject)
                            .build());

            log.debug("对象转移成功: {} -> {}", sourceObject, targetObject);
            return true;

        } catch (MinioException e) {
            log.error("MinIO操作失败: {} -> {}: {}", sourceObject, targetObject, e.getMessage());
            return false;
        } catch (Exception e) {
            log.error("转移对象失败: {} -> {}: {}", sourceObject, targetObject, e.getMessage());
            return false;
        }
    }


    /**
     * 获取文件夹中的所有对象
     */
    private List<MinioObject> listAllObjectsInFolder(String folderPath, boolean includeSubfolders) throws Exception {
        List<MinioObject> objects = new ArrayList<>();

        ListObjectsArgs args = ListObjectsArgs.builder()
                .bucket(bucketName)
                .prefix(folderPath)
                .recursive(includeSubfolders)
                .build();

        Iterable<Result<Item>> results = minioClient.listObjects(args);
        for (Result<Item> result : results) {
            try {
                Item item = result.get();
                // 排除文件夹标记文件
                if (!item.objectName().endsWith(".folder-marker")) {
                    MinioObject minioObject = new MinioObject();
                    minioObject.setObjectName(item.objectName());
                    minioObject.setSize(item.size());
                    minioObject.setLastModified(item.lastModified().toLocalDate());
                    minioObject.setDirectory(item.isDir());
                    objects.add(minioObject);
                }
            } catch (Exception e) {
                log.warn("处理MinIO对象时出错: {}", e.getMessage());
            }
        }

        return objects;
    }

    /**
     * 规范化文件夹路径
     */
    private String normalizeFolderPath(String path, boolean isParentPath) {
        if (path == null) {
            return "";
        }

        path = path.trim();

        // 移除开头的斜杠
        if (path.startsWith("/")) {
            path = path.substring(1);
        }

        // 对于父路径，确保以斜杠结尾
        if (isParentPath && !path.isEmpty() && !path.endsWith("/")) {
            path = path + "/";
        }

        return path;
    }

    /**
     * MinIO对象信息类
     */
    @Data
    public static class MinioObject {
        private String objectName;
        private long size;
        private boolean isDirectory;
        private LocalDate lastModified;

    }

    /**
     * 复制对象
     */
    private void copyObject(String sourceObject, String targetObject) throws Exception {
        minioClient.copyObject(
                CopyObjectArgs.builder()
                        .bucket(bucketName)
                        .object(targetObject)
                        .source(
                                CopySource.builder()
                                        .bucket(bucketName)
                                        .object(sourceObject)
                                        .build())
                        .build());
    }

    /**
     * 删除对象
     */
    private void deleteObject(String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 从路径中提取文件名
     */
    private String extractFileName(String objectPath) {
        if (objectPath.contains("/")) {
            return objectPath.substring(objectPath.lastIndexOf("/") + 1);
        }
        return objectPath;
    }
    /**
     * description: 判断bucket是否存在，不存在则创建
     *
     * @return: void
     */
    public void existBucket(String name) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
            if (!exists) {
                makeBucket(name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 删除存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * description: 下载文件
     *
     * @param fileName
     * @return: org.springframework.http.ResponseEntity<byte [ ]>
     */
    public ResponseEntity<byte[]> download(String fileName, String bucketName) {
        ResponseEntity<byte[]> responseEntity = null;
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            out = new ByteArrayOutputStream();
            IOUtils.copy(in, out);
            //封装返回值
            byte[] bytes = out.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            try {
                headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentLength(bytes.length);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setAccessControlExposeHeaders(Arrays.asList("*"));
            responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseEntity;
    }

    public void uploadFile(String fileName, InputStream fileInputStream) throws Exception {
        try {
            // 检查桶是否存在，不存在则创建
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            // 上传文件
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(fileInputStream, fileInputStream.available(), -1)
                    .contentType("application/octet-stream")
                    .build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 根据bucketName和fileName获取文件的URL
    public String getFileUrl(String bucketName, String fileName) throws Exception {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            throw new Exception("Bucket does not exist");
        }

        // 获取临时URL
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(fileName)
                        .expiry(60 * 60) // URL有效期为1小时
                        .build());
    }

    public List<MinioFileInfoVO> getAllFilesByBucketName(String bucketName) {

        List<MinioFileInfoVO> res = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).recursive(true).build()
        );

        results.forEach(r -> {
            MinioFileInfoVO info = new MinioFileInfoVO();
            try {
                Item item = r.get();
                info.setFileName(item.objectName());
                info.setLastModified(String.valueOf(item.lastModified()));
                res.add(info);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        return res;

    }

    /**
     * 获取指定文件夹下的所有文件和文件夹
     *
     * @param folderPath 文件夹路径，如 "" 表示根目录，"documents/" 或 "documents/subfolder/"
     * @return 包含文件和文件夹信息的列表
     */
    public List<FileObject> listFilesAndFolders(String folderPath) {
        List<FileObject> objects = new ArrayList<>();

        try {
            // 处理根目录情况
            boolean isRoot = folderPath == null || folderPath.isEmpty() || folderPath.equals("/");

            // 规范化路径 - 确保非根目录以"/"结尾
            String normalizedPath = isRoot ? "" :
                    folderPath.endsWith("/") ? folderPath : folderPath + "/";

            // 列出对象
            Iterable<Result<Item>> results = minioClient.listObjects(
                    ListObjectsArgs.builder()
                            .bucket(bucketName)
                            .prefix(normalizedPath)
                            .delimiter("/")  // 使用分隔符来区分文件和文件夹
                            .recursive(false)
                            .build());

            // 处理文件和文件夹
            for (Result<Item> result : results) {
                Item item = result.get();

                // 跳过当前目录本身
                if (item.objectName().equals(normalizedPath)) {
                    continue;
                }

                FileObject fileObject = new FileObject();

                // 处理文件夹
                if (item.isDir()) {
                    String dirName = item.objectName().substring(normalizedPath.length());
                    dirName = dirName.endsWith("/") ? dirName.substring(0, dirName.length() - 1) : dirName;

                    fileObject.setName(dirName);
                    fileObject.setFolderFlag(true);
                    fileObject.setPath(item.objectName());
                }
                // 处理文件
                else {
                    String fileName = item.objectName().substring(normalizedPath.length());

                    // 跳过子目录中的文件（只处理当前目录下的直接文件）
                    if (fileName.contains("/")) {
                        continue;
                    }

                    fileObject.setName(fileName);
                    fileObject.setFolderFlag(false);
                    fileObject.setPath(item.objectName());
                    fileObject.setSize(item.size());
                    fileObject.setLastModified(Date.from(item.lastModified().toInstant()));
                }

                objects.add(fileObject);
            }
        } catch (Exception e) {
            throw new RuntimeException("Error listing files and folders from Minio", e);
        }

        return objects;
    }

    // 获取文件
    public InputStream getFile(String fileName) throws Exception {
        try {
            // 使用 GetObjectArgs 获取对象
            return minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .build()
            );
        } catch (MinioException e) {
            throw new Exception("Error fetching file from Minio: " + e.getMessage(), e);
        }
    }

    //    --------------------------------------------------------
    public void uploadFile(String objectName, MultipartFile file) throws Exception {
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucketName).object(objectName)
                            .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build());
        }
    }

    public InputStream downloadFile(String objectName) throws Exception {
        return minioClient.getObject(
                GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 重命名文件
     *
     * @param oldObjectName 旧文件名（包含路径）
     * @param newObjectName 新文件名（包含路径）
     */
    public void renameFile(String oldObjectName, String newObjectName) throws Exception {
        // 检查旧文件是否存在
        if (!objectExists(oldObjectName)) {
            throw new IllegalArgumentException("源文件不存在");
        }

        // 检查新文件名是否已存在
        if (objectExists(newObjectName)) {
            throw new IllegalArgumentException("目标文件名已存在");
        }

        // 复制文件到新名称
        minioClient.copyObject(
                CopyObjectArgs.builder()
                        .bucket(bucketName)
                        .object(newObjectName)
                        .source(CopySource.builder()
                                .bucket(bucketName)
                                .object(oldObjectName)
                                .build())
                        .build());

        // 删除旧文件
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(oldObjectName)
                        .build());
    }

    /**
     * 检查对象是否存在
     */
    private boolean objectExists(String objectName) throws Exception {
        try {
            minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
            return true;
        } catch (ErrorResponseException e) {
            if (e.response().code() == 404) {
                return false;
            }
            throw e;
        }
    }

    /**
     * 重命名文件夹
     *
     * @param oldFolderPath 旧文件夹路径（以/结尾，如 "old-folder/"）
     * @param newFolderPath 新文件夹路径（以/结尾，如 "new-folder/"）
     */
    public void renameFolder(String oldFolderPath, String newFolderPath) throws Exception {
        // 确保路径以/结尾
        if (!oldFolderPath.endsWith("/")) oldFolderPath += "/";
        if (!newFolderPath.endsWith("/")) newFolderPath += "/";

        // 检查源文件夹是否存在
        if (!folderExists(oldFolderPath)) {
            throw new IllegalArgumentException("源文件夹不存在");
        }

        // 检查目标文件夹是否已存在
        if (folderExists(newFolderPath)) {
            throw new IllegalArgumentException("目标文件夹已存在");
        }

        // 列出文件夹下所有对象
        List<String> objectsToRename = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .prefix(oldFolderPath)
                        .recursive(true)
                        .build());

        for (Result<Item> result : results) {
            Item item = result.get();
            if (!item.isDir()) {
                objectsToRename.add(item.objectName());
            }
        }

        if (objectsToRename.isEmpty()) {
            throw new IllegalArgumentException("源文件夹为空");
        }

        // 逐个重命名
        for (String oldObjectName : objectsToRename) {
            String newObjectName = newFolderPath + oldObjectName.substring(oldFolderPath.length());
            renameFile(oldObjectName, newObjectName);
        }
    }

    /**
     * 检查文件夹是否存在
     */
    private boolean folderExists(String folderPath) throws Exception {
        // 确保路径以/结尾
        if (!folderPath.endsWith("/")) folderPath += "/";

        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .prefix(folderPath)
                        .maxKeys(1)
                        .build());

        return results.iterator().hasNext();
    }


    /**
     * 读取纯文本文件，直接返回为 String
     *
     * @param bucketName
     * @param objectName
     * @return
     * @throws Exception
     */
    public String readTextFile(String bucketName, String objectName) throws Exception {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(
                minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build())))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
                // 添加系统相关的换行符以保持文件的原有格式
                stringBuilder.append(System.lineSeparator());
            }
            return stringBuilder.toString();
        }
    }
}


